EventBridge Schedulerを使ってEC2を定期起動・停止するCloudFormationテンプレート
コスト削減のために、業務時間内だけAmazon EC2インスタンスを起動したいことってありますよね。 9時-18時だけ起動したいとか、週末は停止しておきたいとか。
そんな要望を実現するために、ノンコーディングなAmazon EventBridge Schedulerを使ってEC2を定期起動・停止するAWS CloudFormationテンプレートを紹介します。
Amazon EventBridge Schedulerでコーディング不要なスケジュール実行
AWS上で定期実行したい場合、かつてはAmazon EventBridge rulesでスケジュール実行するのが鉄板でしたが、2022年末にもっと便利なAmazon EventBridge Schedulerがリリースされました。
EventBridge Schedulerを使用すると
- Lambdaなどのコーディング無しに270を超えるAWSサービス、6000以上のAPIを直接を呼び出せる(ユニバーサルターゲット)ため、だれでもメンテナンスできる
- タイムゾーンを指定できるため、時差やサマータイムを考慮せずにスケジュール設定できる
など、管理者に優しい機能が強化されています。
EC2の定期起動・停止設定をCloudFormation化
EventBridge Schedulerを使うと、次のブログのようにコンソールから画面をポチポチするだけで、簡単に設定できてしまいます。
EventBridgeスケジューラを使ってEC2の定期起動/停止を行う方法 | DevelopersIO
EC2の定期起動・停止のような定形作業をより楽をするために、この設定をCloudFormationのテンプレート化してみました。
スタック作成時に
- プルダウンで対象インスタンス
- 起動・停止のスケジュール
- タイムゾーン
を指定するだけです。
CloudFormationテンプレート
Lambdaなどのコードが存在しないため、テンプレートは非常にシンプルです。 設定を指定しているだけです。
--- AWSTemplateFormatVersion: '2010-09-09' Description: EventBridge Scheduler to start/stop EC2 instance Parameters: InstanceId: Type: AWS::EC2::Instance::Id ScheduleStartTime: Type: String Default: "cron(0 8 * * ? *)" ScheduleStopTime: Type: String Default: "cron(0 19 * * ? *)" ScheduleTimezone: Type: String Default: Japan Resources: ScheduleEC2Sart: Type: AWS::Scheduler::Schedule Properties: Name: !Sub 'EC2-Start-${InstanceId}' Description: Start EC2 Instance ScheduleExpression: !Ref ScheduleStartTime ScheduleExpressionTimezone: !Ref ScheduleTimezone FlexibleTimeWindow: Mode: "OFF" State: ENABLED Target: Arn: arn:aws:scheduler:::aws-sdk:ec2:startInstances Input: !Sub |- { "InstanceIds": ["${InstanceId}"] } RoleArn: Fn::GetAtt: - SchedulerEC2StopStartRole - Arn ScheduleEC2Stop: Type: AWS::Scheduler::Schedule Properties: Name: !Sub 'EC2-Stop-${InstanceId}' Description: Stop EC2 Instance ScheduleExpression: !Ref ScheduleStopTime ScheduleExpressionTimezone: !Ref ScheduleTimezone FlexibleTimeWindow: Mode: "OFF" State: ENABLED Target: Arn: arn:aws:scheduler:::aws-sdk:ec2:stopInstances Input: !Sub |- { "InstanceIds": ["${InstanceId}"] } RoleArn: Fn::GetAtt: - SchedulerEC2StopStartRole - Arn SchedulerEC2StopStartRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: - scheduler.amazonaws.com Action: - sts:AssumeRole Path: "/" Policies: - PolicyName: EC2StopStart PolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Action: - ec2:StartInstances - ec2:StopInstances Resource: - "*"
作成されたリソースを確認
このCloudFormationテンプレートは以下のリソースを作成します。
- 起動用と停止用の2つのEventBridge Schedule
- 上記Schedule実行用のIAMロール
スタック作成完了後、コンソールの「Amazon EventBridge > スケジュール」に作成されたリソースを確認できます。
スケジュール通りに起動・停止できていることを確認してください。
CloudFormatationの改善ポイント
本記事では、EventBridge Schdulerのユニバーサルターゲットのサンプルとして、極力シンプルなCloudFormationテンプレートを用意しました。
より実用的にするための改善ポイントを紹介します。
複数のEC2インスタンスを対象にする
今回紹介したテンプレートはスケジュールと対象EC2インスタンスを1:1で作成しています。
ec2:StartInstances
APIec2:StopInstances
API
は複数のインスタンスIDを受け取れるため、CloudFormationパラメータのインスタンスID指定を List<AWS::EC2::Instance::Id>
にかえてターゲットの指定も合わせて調整すると、複数IDに対応できます。
CloudFormationではスケジュールだけを登録し、ターゲットのインスタンスIDリストを手動で管理するのも現実的です。
EC2インスタンス以外を対象にする
EventBridge SchedulerはEC2を含む270のAWSサービス、6000以上のAPIに対応しています。
そのため、RDS/Aurora の自動起動・停止などにも簡単に応用できます。
エラー検知を追加
定期実行を安定運用させるため、実行失敗を検知できるようにデッドレターキューを設定しましょう。
Amazon EventBridge Schedulerのデッドレターキュー(DLQ)を使ってみた | DevelopersIO